package com.heima.user.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.heima.apis.article.IWemediaClient;
import com.heima.common.exception.CustomException;
import com.heima.common.redis.CacheService;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.dtos.LoginDto;
import com.heima.model.user.dtos.UserRelationDto;
import com.heima.model.user.pojos.ApUser;
import com.heima.model.user.pojos.ApUserFan;
import com.heima.model.user.pojos.ApUserFollow;
import com.heima.user.mapper.ApUserFanMapper;
import com.heima.user.mapper.ApUserFollowMapper;
import com.heima.user.mapper.ApUserMapper;
import com.heima.user.service.ApUserService;
import com.heima.utils.common.AppJwtUtil;
import com.heima.utils.common.ApuserThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * APP用户信息表 服务实现类
 * </p>
 *
 * @author itheima
 */
@Slf4j
@Service
@Transactional
public class ApUserServiceImpl extends ServiceImpl<ApUserMapper, ApUser> implements ApUserService {

    @Override
    public ResponseResult login(LoginDto loginDtao) {
        if(!StringUtils.isEmpty(loginDtao.getPhone()) && !StringUtils.isEmpty(loginDtao.getPassword())){
            //查询：根据电话
            ApUser apUser = getOne(Wrappers.<ApUser>lambdaQuery().eq(ApUser::getPhone, loginDtao.getPhone()));
            //判断用户是否存在
            if(apUser == null){
                throw new CustomException(AppHttpCodeEnum.LOGIN_ERROR);
            }
            //校验密码
            String srcPassword = DigestUtils.md5DigestAsHex((loginDtao.getPassword() + apUser.getSalt()).getBytes());
            if(!srcPassword.equals(apUser.getPassword())){
                throw new CustomException(AppHttpCodeEnum.LOGIN_ERROR);
            }
            //封装返回参数
            String token = AppJwtUtil.getToken(apUser.getId().longValue());
            Map<String,Object> map = new HashMap<>();
            map.put("token",token);
            //将盐和密码设置为空
            apUser.setSalt("");
            apUser.setPassword("");
            map.put("user",apUser);
            return ResponseResult.okResult(map);
        } else {
            String token = AppJwtUtil.getToken(0L);
            Map<String,Object> map = new HashMap<>();
            map.put("token",token);
            return ResponseResult.okResult(map);
        }

    }

    @Autowired
    private CacheService cacheService;

    @Autowired
    private ApUserFanMapper apUserFanMapper;

    @Autowired
    private ApUserFollowMapper apUserFollowMapper;

    @Autowired
    private ApUserMapper apUserMapper;

    @Autowired
    private IWemediaClient wemediaClient;
    /**
     * 关注功能
     * @param dto
     * @return
     */
    @Override
    public ResponseResult userFollow(UserRelationDto dto) {
        //1.参数检查
        if (dto == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //2.从线程中去获取用户信息   获取当前用户登录的id
        ApUser apUser = ApuserThreadLocalUtil.get();
        if (apUser ==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        //3.获取用户的id
        Integer apUserId = null;
        if (apUser != null){
            apUserId = apUser.getId();
            if (apUserId == 0){
                return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
            }
        }
        //4.将数据存储到redis中
        //定义一个唯一的key
        String key = "FOLLOW_" + apUserId;
        Map<String, String> map = new HashMap<>();
        map.put("articleId",dto.getArticleId() + "");
        map.put("authorId",dto.getAuthorId()+"");
        map.put("operation",dto.getOperation() + "");


        cacheService.hPut(key,dto.getArticleId() + "", JSON.toJSONString(map));

        //cacheService.hPutAll(key,map);

        //5.判断是关注还是取消关注
        if (dto.getOperation() == 0){
            //关注  需要保存ap_user_follow 和 ao_user_fan表
            ApUserFollow apUserFollow = new ApUserFollow();
            apUserFollow.setUserId(apUserId);
            apUserFollow.setFollowId(dto.getAuthorId());
            //关注作者的名称需要通过feign调用去自媒体端获取用户的名称
            String wemediaClientName = wemediaClient.getName(dto.getAuthorId());
            apUserFollow.setFollowName(wemediaClientName);
            apUserFollow.setLevel(true);
            apUserFollow.setIsNotice(false);
            apUserFollow.setCreatedTime(new Date());
            //保存
            apUserFollowMapper.insert(apUserFollow);

            //保存ao_user_fan表
            ApUserFan apUserFan = new ApUserFan();
            apUserFan.setUserId(dto.getAuthorId());
            apUserFan.setFansId(apUserId);
            //通过apUserId查询当前登录用户信息
            ApUser user = apUserMapper.selectById(apUserId);
            apUserFan.setFansName(user.getName());
            apUserFan.setLevel(false);
            apUserFan.setCreatedTime(new Date());
            apUserFan.setIsDisplay(false);
            apUserFan.setIsShieldComment(false);
            apUserFan.setIsShieldLetter(false);
            //保存到数据库
            apUserFanMapper.insert(apUserFan);
        }else {
            //取消关注  删除ap_user_follow 和 ao_user_fan表中的数据
            LambdaQueryWrapper<ApUserFollow> aPWrapper = new LambdaQueryWrapper<>();
            aPWrapper.eq(ApUserFollow::getUserId,apUserId);
            aPWrapper.eq(ApUserFollow::getFollowId,dto.getAuthorId());
            apUserFollowMapper.delete(aPWrapper);

            LambdaQueryWrapper<ApUserFan> fanLambdaQueryWrapper = new LambdaQueryWrapper<>();
            fanLambdaQueryWrapper.eq(ApUserFan::getFansId,apUserId);
            fanLambdaQueryWrapper.eq(ApUserFan::getUserId,dto.getArticleId());
            apUserFanMapper.delete(fanLambdaQueryWrapper);
        }

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

}
